package com.cqw.commontest.stream;

import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: caoqingwen
 * @CreateTime: 2021-04-08 16:09
 * @Description:
 */
@Slf4j
public class StreamTest {

    public static void main(String[] args) {
        //List<User> users = null;
        List<User> users = new ArrayList<>();
        users.add(new User(1L, "张三", 23, "123456@qq.com", "敲代码"));
        users.add(new User(2L, "李四", 23, "123456@qq.com", "敲代码"));
        users.add(new User(3L, "王五", 23, "123456@qq.com", "敲代码"));
        users.add(new User(4L, "赵六", 23, "123456@qq.com", "敲代码"));


        List<User> collect13 = users.stream().sorted(Comparator.comparing(User::getId)).sorted(Comparator.comparing(User::getAge))
                .
                collect(Collectors.toList());
        for (User user : collect13) {
            System.out.println(user);
        }


        //users.forEach(user -> System.out.println("====="));
        Stream<Long> longStream = users.stream()
                .map(User::getId);

        //users.forEach(System.out::println);

        List<User> collect = users.stream().filter(user -> user.getAge() > 23).collect(Collectors.toList());

        //collect.forEach(System.out::println);


        /**
         * map使用
         */
        List<String> list = Arrays.asList("java", "php", "vue");

        //转大写
        List<String> collect1 = list.stream().map(String::toUpperCase).collect(Collectors.toList());

        //collect1.forEach(System.out::println);

        //转换数据类型


        List<String> list1 = new ArrayList<>();
        //Stream流的filter使用
        String any = list1
                .stream()
                .findAny().orElse("111");
        //System.out.println(any);

        //年龄总和
        int sum = users.stream().filter(user -> user.getAge() != 24).mapToInt(User::getAge).sum();
        //System.out.println(sum);

        //Stream流的flatMap使用
        List<String> strings = Arrays.asList("Hello", "world");
        List<String[]> collect2 = strings.stream().map(s -> s.split("")).collect(Collectors.toList());
        //collect2.forEach(System.out::println);

        String words = "You look perfect";
        List<String> wordList = new ArrayList<>();
        wordList.add(words);
//        wordList.stream().flatMap(str->)


        /**
         * Stream流的limit使用
         * limit方法用于获取指定数量的流
         * 获取前n条数的数据
         */
        Random random = new Random();
        //random.ints().limit(4).forEach(System.out::println);


        /**
         * 结合skip使用得到需要的数据
         * skip表示扔掉前n个数据
         */
        List<String> collect3 = users.stream().map(User::getName).limit(3).skip(3).collect(Collectors.toList());
        //collect3.stream().forEach(System.out::println);


        /**
         * stream流的sort使用
         * sorted方法用于对流进行升序排序
         */
        //List<User> collect4 = users.stream().sorted().collect(Collectors.toList());
        //collect4.forEach(System.out::println);

       /* List<User> collect5 = users.stream().sorted(Comparator.reverseOrder())
                .collect(Collectors.toList());
        collect5.forEach(System.out::println);*/


        List<User> collect5 = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
        //collect5.forEach(System.out::println);

        List<User> collect4 = users.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
        //collect4.forEach(System.out::println);


        /**
         * stream流的peek使用
         * peek对每一个元素执行操作并返回一个新的stream
         * 双重操作
         */


        /**
         * stream流的max/min/distinct
         */
        List<String> names = Arrays.asList("zhangsan", "lisi", "wangwu");
        int asInt = names.stream().mapToInt(String::length).max().getAsInt();
        System.out.println(asInt);


        /**
         * stream流的Match使用
         * allMatch:Stream全部元素符合则返回true
         * anyMatch:Stream只要有一个元素符合就返回true
         * noneMatch:Stream中没有一个元素符合就返回true
         */
        boolean allMatch = users.stream().allMatch(user -> user.getAge() > 30);
        //System.out.println(allMatch);
        boolean anyMatch = users.stream().anyMatch(user -> user.getAge() > 30);
        //System.out.println(anyMatch);
        boolean noneMatch = users.stream().noneMatch(user -> user.getAge() > 30);
        //System.out.println(noneMatch);


        /**
         * Stream流的reduce使用
         * reduce主要作用是把Stream元素组合起来进行操作
         */
        //字符串拼接
        List<String> strs = Arrays.asList("A", "B", "C", "D");
        String reduce = strs.stream().reduce(",", String::concat);
        //System.out.println(reduce);

        String s = strs.stream()
                .reduce(String::concat)
                .get();
        //System.out.println(s);


        //求最小值
        List<Integer> integers = Arrays.asList(1, 2, 3, 4);
        Integer integer = integers.stream().reduce(Integer::max).get();
        //System.out.println(integer);

        //求和
        Integer integer1 = integers.stream().reduce(Integer::sum).get();
        System.out.println(integer1);


        //求和，有初始值
        Integer integer2 = integers.stream().reduce(5, Integer::sum);
        System.out.println(integer2);


        /**
         * Stream流的grouping by 分组
         * 根据年龄分组
         */

        /**
         * 按年龄分组
         */
        Map<Integer, List<User>> listMap = users.stream().collect(Collectors.groupingBy(User::getAge));

        for (Integer integer3 : listMap.keySet()) {
            //System.out.println(integer3 + "========" + listMap.get(integer3));
        }


        /**
         * 按年龄分组并统计每个分组的count
         */
        Map<Integer, Long> collect6 = users.stream().collect(Collectors.groupingBy(User::getAge, Collectors.counting()));

        for (Integer integer3 : collect6.keySet()) {
            //System.out.println(integer3 + "===========================" + collect6.get(integer3));
        }


        /**
         * 按邮箱分组并求平均值
         */
        Map<String, Double> collect7 = users.stream().collect(Collectors.groupingBy(User::getEmail, Collectors.averagingInt(User::getAge)));
        for (String integer3 : collect7.keySet()) {
            //System.out.println(integer3 + "=======================================" + collect7.get(integer3));
        }


        /**
         * 分组并求分组总值
         */
        Map<String, Integer> collect8 = users.stream().collect(Collectors.groupingBy(User::getEmail, Collectors.summingInt(User::getAge)));

        for (String s1 : collect8.keySet()) {
            //System.out.println(s1 + "==========" + collect8.get(s1));
        }


        /**
         * 分组之join分组list
         *  按邮箱分组，并通过join将
         */
        Map<String, String> collect9 = users.stream()
                .collect(Collectors.groupingBy(User::getEmail, Collectors.mapping(User::getName, Collectors.joining(",", "[", "]"))));

        for (String s1 : collect9.keySet()) {
            System.out.println(s1 + "================" + collect9.get(s1));
            //123456@qq.com================[张三,李四,王五,赵六]
        }


        /**
         * 分组之转换分组结果List -> List
         */
        Map<String, List<Integer>> collect10 = users.stream()
                .collect(Collectors.groupingBy(User::getEmail, Collectors.mapping(User::getAge, Collectors.toList())));

        for (String s1 : collect10.keySet()) {
            //System.out.println(s1 + "=============" + collect10.get(s1));
            //123456@qq.com=============[21, 22, 23, 24]
        }


        /**
         * 分组之使用对象分组list
         */
        Map<Student, List<User>> collect11 = users.stream().collect(Collectors.groupingBy(user -> new Student(user.getName())));
        for (Student student : collect11.keySet()) {
            //System.out.println(student + "=============" + collect11.get(student));
            /*Student(name=赵六)=============[User(id=4, name=赵六, age=24, email=123456@qq.com, hobby=敲代码)]
            Student(name=李四)=============[User(id=2, name=李四, age=22, email=123456@qq.com, hobby=敲代码)]
            Student(name=王五)=============[User(id=3, name=王五, age=23, email=123456@qq.com, hobby=敲代码)]
            Student(name=张三)=============[User(id=1, name=张三, age=21, email=123456@qq.com, hobby=敲代码)]*/
        }


        /**
         * 分组之使用两个成员分组list
         */
        Map<String, Map<Integer, List<User>>> collect12 = users.stream().collect(Collectors.groupingBy(User::getEmail, Collectors.groupingBy(User::getAge)));

        for (String s1 : collect12.keySet()) {
            Map<Integer, List<User>> stringListMap = collect12.get(s1);
            for (Integer s2 : stringListMap.keySet()) {
                //System.out.println(s1 + "=====" + s2 + "========" + stringListMap.get(s2));
            }
        }


    }


}
